<template>
  <div class="truth-table-container">
    <h3>真值表生成器</h3>
    <div class="input-section">
      <a-input 
        v-model:value="formula" 
        placeholder="请输入命题公式，例如: (P ∧ Q) ∨ (¬P ∧ R)"
        style="width: 300px; margin-right: 10px;"
        @keyup.enter="generateTruthTable"
      />
      <a-button type="primary" @click="generateTruthTable">生成真值表</a-button>
    </div>
    
    <div v-if="variables.length > 0" class="variables-section">
      <h4>变量说明:</h4>
      <div class="variables-list">
        <span v-for="variable in variables" :key="variable" class="variable-tag">
          {{ variable }}
        </span>
      </div>
    </div>
    
    <div v-if="truthTable.length > 0" class="table-section">
      <h4>真值表:</h4>
      <div class="table-wrapper">
        <table class="truth-table">
          <thead>
            <tr>
              <th v-for="variable in variables" :key="variable">{{ variable }}</th>
              <th>{{ formula }}</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(row, index) in truthTable" :key="index">
              <td v-for="variable in variables" :key="variable">
                {{ row.assignments[variable] ? 'T' : 'F' }}
              </td>
              <td :class="{ 'result-true': row.result, 'result-false': !row.result }">
                {{ row.result ? 'T' : 'F' }}
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
    
    <div v-if="error" class="error-section">
      <a-alert type="error" :message="error" banner />
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';

const formula = ref('');
const variables = ref([]);
const truthTable = ref([]);
const error = ref('');

// 简单的公式解析和计算函数
const parseAndEvaluate = (formula, assignments) => {
  try {
    // 替换逻辑运算符为 JavaScript 运算符
    let processedFormula = formula
      .replace(/∧/g, '&&')           // 与
      .replace(/∨/g, '||')           // 或
      .replace(/¬/g, '!')            // 非
      .replace(/→/g, '=>')           // 蕴含
      .replace(/↔/g, '===')          // 等价
      
      // 替换变量为对应的布尔值
      .replace(/\b([A-Z])\b/g, (match) => {
        return assignments[match] ? 'true' : 'false';
      });
    
    // 特殊处理蕴含运算符 => 的转换
    processedFormula = processedFormula.replace(/=>/g, 'implies');
    
    // 定义蕴含函数
    const implies = (a, b) => !a || b;
    
    // 计算表达式
    // 注意：这里使用了 eval，仅用于演示目的，在生产环境中应使用更安全的解析器
    const result = eval(processedFormula);
    return Boolean(result);
  } catch (e) {
    throw new Error('公式格式错误');
  }
};

// 获取公式中的变量
const extractVariables = (formula) => {
  const variableRegex = /\b([A-Z])\b/g;
  const matches = formula.match(variableRegex);
  return matches ? [...new Set(matches)] : [];
};

// 生成所有可能的变量赋值组合
const generateAssignments = (variables) => {
  const assignments = [];
  const totalCombinations = Math.pow(2, variables.length);
  
  for (let i = 0; i < totalCombinations; i++) {
    const assignment = {};
    for (let j = 0; j < variables.length; j++) {
      // 使用位运算确定每个变量的值
      assignment[variables[j]] = Boolean(i & (1 << j));
    }
    assignments.push(assignment);
  }
  
  return assignments;
};

// 生成真值表
const generateTruthTable = () => {
  try {
    if (!formula.value.trim()) {
      error.value = '请输入命题公式';
      return;
    }
    
    // 清除之前的错误
    error.value = '';
    
    // 提取变量
    variables.value = extractVariables(formula.value);
    
    if (variables.value.length === 0) {
      error.value = '公式中未找到变量';
      return;
    }
    
    // 生成所有可能的赋值组合
    const assignments = generateAssignments(variables.value);
    
    // 计算每种赋值下的结果
    truthTable.value = assignments.map(assignment => {
      return {
        assignments: assignment,
        result: parseAndEvaluate(formula.value, assignment)
      };
    });
  } catch (e) {
    error.value = e.message || '生成真值表时发生错误';
  }
};
</script>

<style scoped>
.truth-table-container {
  padding: 20px;
}

.input-section {
  display: flex;
  align-items: center;
  margin-bottom: 20px;
}

.variables-section {
  margin-bottom: 20px;
}

.variables-section h4 {
  margin-bottom: 10px;
}

.variables-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.variable-tag {
  background-color: #f0f2f5;
  padding: 4px 12px;
  border-radius: 16px;
  font-size: 14px;
}

.table-section {
  margin-top: 20px;
}

.table-section h4 {
  margin-bottom: 10px;
}

.table-wrapper {
  overflow-x: auto;
}

.truth-table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 20px;
}

.truth-table th,
.truth-table td {
  border: 1px solid #e8e8e8;
  padding: 12px 16px;
  text-align: center;
}

.truth-table th {
  background-color: #fafafa;
  font-weight: 600;
}

.result-true {
  background-color: #f6ffed;
  color: #52c41a;
  font-weight: bold;
}

.result-false {
  background-color: #fff2f0;
  color: #ff4d4f;
  font-weight: bold;
}

.error-section {
  margin-top: 20px;
}
</style>